#include <pspkernel.h>
#include <pspsdk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pspctrl.h>
#include "kerror.h"
#include "splash.h"
#include <time.h>

PSP_MODULE_INFO("PSP3JB", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);

SceCtrlData pad;
#include "gui.c"
#include "procs.c"
#include "..\states.h"



/* comm */
int getModelKernel();

int register_udriver();
int start_mainusbbus();
int start_mainusbdrv();
int activate_usbdriv();
int drivers_stop_all();

void stepperfunction(struct passingdata *ptr);

int running = 1;

/* Callbacks */
int exit_callback(int arg1, int arg2, void *common) { running = 0; drivers_stop_all(); sceKernelExitGame(); return 0; }
static int CallbackThread(SceSize args, void *argp) {
   int cbid; 
   cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
   sceKernelRegisterExitCallback(cbid);
   sceKernelSleepThreadCB();
   return 0;
}
static int SetupCallbacks(void) {
   int thid = 0;
   thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
   if(thid >= 0) { sceKernelStartThread(thid, 0, 0); }
   return thid;
}

int timeout = 0;
clock_t now = 0;
clock_t endtime = 0;

static clock_t getCurrentMilliseconds() {
	return (clock() / (clock_t)(CLOCKS_PER_SEC *0.001));
}

int main(int argc, char *argv[]) {
	SetupCallbacks();
	screeninit();
	sceCtrlSetSamplingCycle(0);
	sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL);
	
	#ifdef SPLASH0
		// regex from:	<span style="color:#([0-9A-F][0-9A-F])([0-9A-F][0-9A-F])([0-9A-F][0-9A-F])">([A-Z])</span>
		// to: 			fcolor(0xFF\3\2\1); printf("\3");
		SPLASH0
		zzz(10);
	#endif
		
	//INITING...	
	fcolor(ABGR(155,155,155,255)); apl("[*] "); fcolor(ABGR(255,255,255,255)); apl("Creado por DeViaNTe. X para continuar. O para salir.");	
	//INIT DRIVER OR EXIT...
	while (1) {
		sceCtrlReadBufferPositive(&pad,1);
		if ( pad.Buttons & PSP_CTRL_CROSS ) { cls(); driverint("usbdriver.prx"); break; } 
		if ( pad.Buttons & PSP_CTRL_CIRCLE ) { sceKernelExitGame(); } 
	}

	apl("\n\n");
	
	while (1) {
		resetdata(&res);
		res.status = estado;
		if ( endtime > 0 ) {
			if ( now > endtime ) { res.timeout = 0; }
			else { res.timeout = 1; }
		}
		
		
		stepperfunction(&res);
		estado = res.status;
		
		switch (estado) {
			case APP_INIT:
				fcolor(ABGR(155,155,155,255)); apl("[D] "); fcolor(ABGR(255,255,255,255)); apl(res.text);
				fcolor(ABGR(155,155,155,255)); apl("[D] "); fcolor(ABGR(255,255,255,255)); aplf("Registrando driver : %s\n",ERROR_STR(register_udriver()));
				fcolor(ABGR(155,155,155,255)); apl("[D] "); fcolor(ABGR(255,255,255,255)); aplf("Inciando BUS USB   : %s\n",ERROR_STR(start_mainusbbus()));
				fcolor(ABGR(155,155,155,255)); apl("[D] "); fcolor(ABGR(255,255,255,255)); aplf("Inciando USB DRV   : %s\n",ERROR_STR(start_mainusbdrv()));
				fcolor(ABGR(155,155,155,255)); apl("[D] "); fcolor(ABGR(255,255,255,255));  apl("Temporalmente probar con 2 puertos.\n");
				fcolor(ABGR(155,155,155,255)); apl("[D] "); fcolor(ABGR(255,255,255,255)); aplf("Activar dispositivo: %s\n",ERROR_STR(activate_usbdriv()));
				apl("\n\n");
				cls();
				break;
			case APP_READY:
				pl(res.text);
				break;
			case APP_HUB_READY:
				now = getCurrentMilliseconds();
				if ( res.timeout > 0 ) { /* GOT TIMEOUT */
					timeout = res.timeout;
					fcolor(ABGR(155,155,155,255)); 	pl("[T] ");  fcolor(ABGR(255,255,255,255));  pf("Temporizador: %i ms\n",timeout);
					endtime = now + timeout;
				}
				if ( endtime > 0 && now > endtime ) { 
					endtime = 0; fcolor(ABGR(155,155,155,255)); 	pl("[T] "); fcolor(ABGR(0,255,0,255));  pl("RIIING\n"); fcolor(ABGR(255,255,255,255));
				}
				pl(res.text);
				break;
				
			case APP_DEV1_WAIT:
				pl(res.text);
				break;
			
			case APP_TERM:
				appkilled();
				break;
				
			default:
				break;
		}
		
		if ( running == 0 ) { sceKernelExitGame(); }
	}
	
	return 0;
}
